import { NodeSSH } from "node-ssh";
import { execSync } from "child_process"; // 引入 child_process 用于本地打包
import { deployConfig } from "./config.js";
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';

// --- 新增配置 ---
// 定义要上传的本地目录和服务器上的目标目录
const LOCAL_DIR_TO_UPLOAD = './../dist'; // 假设你要上传本地的 'dist' 目录
const SERVER_TARGET_DIR = 'C:\\nginx-1.29.2\\html\\www\\vite-template'; // 服务器上的目标目录
const ARCHIVE_NAME = 'deploy-package.tar.gz'; // 压缩包的名称
const LOCAL_ARCHIVE_PATH = join(dirname(fileURLToPath(import.meta.url)), ARCHIVE_NAME); // 本地压缩包的完整路径
const SERVER_ARCHIVE_PATH = `C:\\temp\\${ARCHIVE_NAME}`; // 服务器上临时存放压缩包的路径
// --- 配置结束 ---

async function deploy() {
    console.log("开始部署流程...");
    const ssh = new NodeSSH();
    
    // 监听连接错误事件，防止未处理的错误
    ssh.connection?.on('error', (err) => {
        if (err.code === 'ECONNRESET') {
            console.log("⚠️  连接被重置（Windows SSH 正常现象）");
        } else {
            console.log("连接错误:", err.message);
        }
    });

    try {
        // --- 步骤 1: 本地打包 ---
        console.log(`🗜️  正在打包本地目录 '${LOCAL_DIR_TO_UPLOAD}'...`);
        // 使用 tar 命令打包，-c 创建, -z gzip压缩, -f 指定文件名
        // 注意：这个命令在 Windows 10/11/Server 2022+ 上通常可用
        execSync(`tar -czf ${ARCHIVE_NAME} -C ${dirname(LOCAL_DIR_TO_UPLOAD)} ${basename(LOCAL_DIR_TO_UPLOAD)}`, { stdio: 'inherit' });
        console.log(`✅ 本地打包完成，生成文件: ${LOCAL_ARCHIVE_PATH}`);

        // --- 步骤 2: 连接服务器 ---
        console.log("🔌 连接到服务器...");
        await ssh.connect(deployConfig);
        console.log("✅ 连接成功 - Windows Server 2025 Datacenter");

        // --- 步骤 3: 在服务器上准备目录 ---
        console.log(`🛠️  在服务器上创建目标目录 '${SERVER_TARGET_DIR}' (如果不存在)...`);
        // PowerShell 命令：如果目录不存在则创建
        await ssh.execCommand(`powershell -Command "if (-not (Test-Path -Path '${SERVER_TARGET_DIR}')) { New-Item -ItemType Directory -Path '${SERVER_TARGET_DIR}' }"`);
        console.log("✅ 目标目录已准备就绪。");

        // --- 步骤 4: 上传压缩包 ---
        console.log(`📤 正在上传压缩包到服务器 '${SERVER_ARCHIVE_PATH}'...`);
        await ssh.putFile(LOCAL_ARCHIVE_PATH, SERVER_ARCHIVE_PATH);
        console.log("✅ 压缩包上传成功！");

        // --- 步骤 5: 在服务器上解压 ---
        console.log(`📂 正在服务器上解压到 '${SERVER_TARGET_DIR}'...`);
        // Windows tar 命令: -x 解压, -z gzip, -f 指定文件, -C 指定目标目录
        // 使用 PowerShell 执行，确保路径解析正确
        const untarResult = await ssh.execCommand(`powershell -Command "tar -xzf '${SERVER_ARCHIVE_PATH}' -C '${SERVER_TARGET_DIR}'"`);
        if (untarResult.stderr) {
            // tar 在 Windows 上有时会把一些非致命信息输出到 stderr，我们检查一下
            console.warn("解压时产生警告/信息:", untarResult.stderr);
        }
        console.log("✅ 服务器端解压完成！");

        // --- 步骤 6: 清理服务器上的临时压缩包 ---
        console.log(`🧹 正在删除服务器上的临时压缩包 '${SERVER_ARCHIVE_PATH}'...`);
        await ssh.execCommand(`del "${SERVER_ARCHIVE_PATH}"`);
        console.log("✅ 服务器临时文件已清理。");

        console.log("\n🎉 部署成功！所有文件已上传并解压。");

        // --- (可选) 保留原有的系统检查功能 ---
        console.log("\n--- 开始执行系统检查 ---");
        console.log("执行系统检查...");
        
        const diskResult = await ssh.execCommand("wmic logicaldisk get caption,size,freespace");
        console.log("磁盘空间信息:\n", diskResult.stdout);

        const memoryResult = await ssh.execCommand("wmic OS get FreePhysicalMemory,TotalVisibleMemorySize /Value");
        console.log("内存信息:\n", memoryResult.stdout);

        const networkResult = await ssh.execCommand("ipconfig | findstr IPv4");
        console.log("网络信息:\n", networkResult.stdout);
        console.log("--- 系统检查完成 ---");

    } catch (error) {
        console.error("❌ 部署失败:", error.message);
    } finally {
        // --- 步骤 7: 清理本地的临时压缩包 ---
        try {
            execSync(`del "${LOCAL_ARCHIVE_PATH}"`, { stdio: 'inherit' });
            console.log(`🧹 本地临时压缩包 '${LOCAL_ARCHIVE_PATH}' 已清理。`);
        } catch (cleanupError) {
            // 忽略清理时可能发生的错误（例如文件不存在）
        }

        // 安全关闭连接
        await safeDisconnect(ssh);
    }
}

// 安全关闭连接
async function safeDisconnect(ssh) {
    return new Promise((resolve) => {
        setTimeout(() => {
            try {
                ssh.dispose();
                console.log("🔌 SSH 连接已关闭");
            } catch (error) {
                // 忽略关闭时的任何错误
            }
            resolve();
        }, 500);
    });
}

// 为了在打包命令中使用 dirname 和 basename，需要导入它们
import { basename } from 'path';

deploy();
